// Copyright 2021 by 马万里. All rights reserved.
// 开发团队 ：   鸡中之霸
// 开发人员 ：   马万里
// 开发时间 ：   2021/2/21 18:19
// 文件名称 ：   api.go
// 工程名称 ：   videostream
// 开发工具 ：   GoLand
//

package dbops

import (
	"database/sql"
	"fmt"
	"johnsonsmile.com/videostream/api/defs"
	"johnsonsmile.com/videostream/api/utils"
	"log"
	"time"
)

// 用户部分
func AddUserCredential(name string, pwd string) error {
	s := "INSERT INTO users (username, password) VALUES (?, ?)"
	stmt, err := db.Prepare(s)
	defer stmt.Close()
	if err != nil {
		return err
	}
	_, err = stmt.Exec(name, pwd)
	if err != nil {
		return err
	}
	return nil
}

func GetUserCredential(name string) (string, error) {
	s := "SELECT password FROM users WHERE username = ?"
	stmt, err := db.Prepare(s)
	defer stmt.Close()
	if err != nil {
		return "", err
	}
	var pwd string
	stmt.QueryRow(name).Scan(&pwd)
	return pwd, nil
}

func DeleteUser(name string, pwd string) error {

	s := "DELETE FROM users WHERE username = ? AND password = ?"
	stmt, err := db.Prepare(s)
	if err != nil {
		return err
	}
	defer stmt.Close()
	_, err = stmt.Exec(name, pwd)
	if err != nil {
		return err
	}
	return nil
}

func GetUser(loginName string) (*defs.User, error) {
	stmtOut, err := db.Prepare("SELECT id, password FROM users WHERE username = ?")
	if err != nil {
		return nil, err
	}

	var id int
	var pwd string

	err = stmtOut.QueryRow(loginName).Scan(&id, &pwd)
	if err != nil && err != sql.ErrNoRows {
		return nil, err
	}

	if err == sql.ErrNoRows {
		return nil, nil
	}

	res := &defs.User{Id: id, LoginName: loginName, Pwd: pwd}

	defer stmtOut.Close()

	return res, nil
}

// 视频部分
func AddNewVideo(aid int, name string) (*defs.VideoInfo, error) {
	// create uuid
	vid, err := utils.NewUUID()
	if err != nil {
		return nil, err
	}

	t := time.Now()
	ctime := t.Format("Jan 02 2006, 15:04:05")
	stmtIns, err := db.Prepare(`INSERT INTO video 
		(id, author_id, name, display_ctime) VALUES(?, ?, ?, ?)`)
	if err != nil {
		return nil, err
	}

	_, err = stmtIns.Exec(vid, aid, name, ctime)
	if err != nil {
		return nil, err
	}

	res := &defs.VideoInfo{Id: vid, AuthorId: aid, Name: name, DisplayCtime: ctime}
	fmt.Println("res", res)
	defer stmtIns.Close()
	return res, nil
}

func GetVideoInfo(vid string) (*defs.VideoInfo, error) {
	stmtOut, err := db.Prepare("SELECT author_id, name, display_ctime FROM video WHERE id=?")

	var aid int
	var dct string
	var name string

	err = stmtOut.QueryRow(vid).Scan(&aid, &name, &dct)
	if err != nil && err != sql.ErrNoRows {
		return nil, err
	}

	if err == sql.ErrNoRows {
		return nil, nil
	}

	defer stmtOut.Close()

	res := &defs.VideoInfo{Id: vid, AuthorId: aid, Name: name, DisplayCtime: dct}

	return res, nil
}

func ListVideoInfo(uname string, from, to int) ([]*defs.VideoInfo, error) {
	stmtOut, err := db.Prepare(`SELECT video.id, video.author_id, video.name, video.display_ctime FROM video 
		INNER JOIN users ON video.author_id = users.id
		WHERE users.login_name = ? AND video.create_time > FROM_UNIXTIME(?) AND video.create_time <= FROM_UNIXTIME(?) 
		ORDER BY video.create_time DESC`)

	var res []*defs.VideoInfo

	if err != nil {
		return res, err
	}

	rows, err := stmtOut.Query(uname, from, to)
	if err != nil {
		log.Printf("%s", err)
		return res, err
	}

	for rows.Next() {
		var id, name, ctime string
		var aid int
		if err := rows.Scan(&id, &aid, &name, &ctime); err != nil {
			return res, err
		}

		vi := &defs.VideoInfo{Id: id, AuthorId: aid, Name: name, DisplayCtime: ctime}
		res = append(res, vi)
	}

	defer stmtOut.Close()

	return res, nil
}

func DeleteVideoInfo(vid string) error {
	stmtDel, err := db.Prepare("DELETE FROM video WHERE id=?")
	if err != nil {
		return err
	}

	_, err = stmtDel.Exec(vid)
	if err != nil {
		return err
	}

	defer stmtDel.Close()
	return nil
}

// 评论部分
func AddNewComments(vid string, aid int, content string) error {
	id, err := utils.NewUUID()
	if err != nil {
		return err
	}
	stmtIn, err := db.Prepare("INSERT INTO comments (id, video_id, author_id, content) VALUES (?, ?, ?, ?)")
	if err != nil {
		return err
	}
	defer stmtIn.Close()
	_, err = stmtIn.Exec(id, vid, aid, content)
	if err != nil {
		return err
	}
	return nil
}

func ListComments(vid string, from, to int) ([]*defs.Comment, error) {
	stmtOut, err := db.Prepare(`SELECT comments.id, users.username, comments.content FROM comments
		INNER JOIN users ON comments.author_id = users.id
		WHERE comments.video_id = ? AND comments.create_time > FROM_UNIXTIME(?) AND comments.create_time <= FROM_UNIXTIME(?)
		ORDER BY comments.create_time DESC`)
	var res []*defs.Comment
	if err != nil {
		return res, err
	}
	defer stmtOut.Close()
	rows, err := stmtOut.Query(vid, from, to)
	if err != nil {
		return res, err
	}
	for rows.Next() {
		var id, name, content string
		if err := rows.Scan(&id, &name, &content); err != nil {
			return res, err
		}
		c := &defs.Comment{
			Id:      id,
			VideoId: vid,
			Author:  name,
			Content: content,
		}
		res = append(res, c)
	}
	return res, nil
}
